#***************************************************************************************************************** # # AdoScript File of Industrial_Business_Process_Management_ADOxx15-v0.3.0 Application Library # # AdoScript for Simulation of Production on Production lines defined by Block Diagrams per Production Amount # #------------------------- GENERAL FILE INFOS -------------------------------------------------------------------- # # APPLIES TO: Industrial Business Process Management Toolkit V:1.0 # FILE VERSION: 1.0 # AUTHOR: NEF (BOC AM) # #--------------------------- FILE DEPENDENCIES ------------------------------------------------------------------- # # INCLUDING FILES: 'ASC_RandomDistributions.asc', 'Procedure_ADOTIME_TO_SEC.asc', 'Procedure_SEC_TO_ADOTIME.asc' # # INCLUDED BY: None # #--------------------------- READ BEFORE EDIT -------------------------------------------------------------------- # # --- File History --- # # [NEF, 09.11.2017] # - initial version for Industrial Business Process Management Toolkit # # USAGE: The mechanism triggered by PROGRAMCALL type attribute 'Simulate Production per Production Amount' # through NOTEBOOK of selected 'Buffer' object. # # REMARKS: - Industrial_Business_Process_Management_ADOxx15-v0.3.0 Application Library is based # on StartingPoint_BPMN2-0_ADOxx1-3-UL1_v1-01.abl # (https://www.adoxx.org/svn/all-repo/4_StartingPoint_BPMN2.0_ADOxx13UL1/BIN/StartingPoint_BPMN2-0_ADOxx1-3-UL1_v1-01.abl) # provided by ADOxx.org. # # - CLASS 'Group' from BPMN implementation on ADOxx represents stations in production processes # This design decision is based on the rationale to modify initial BPMN implementation on # ADOxx as less as possible. # #--------------------------- EXECUTION SCENARIO ------------------------------------------------------------------ # PRELIMINARY INFO: # -'Buffer' object provides input part/materials required by station (Group Object), or stores # output part/material produced by station. # -'Station' (Group Object) consumes parts/materials as inputs from buffer, and other resources # like time, money, labour etc., processes and produces parts/materials/final products as outputs. # -Check for details the meta-model of Industrial Business Process Management. #----------------------------------------------------------------------------------------------------------------- # 1-User selects a Buffer in any part of production line to simulate whole production line or part of # production line # 2-User enters production amount in interest to simulate production line # 3-Algorithm gets stations ('Group' in BPMN on ADOxx Application Library) backwards.For each # station algorithm registers execution time per (semi-)product production, update required # part/material in BoM per 'Quantity' specified in each outgoing 'Parts flow' to buffers. # 4-Algorithm gets buffers backwards. For each buffer algorithm calculates required amount of # part/materials, that will be pulled by successor station depending on 'Quantity' specified in # each outgoing 'Part flow' to stations # !!! Please Note !!! # As successor station(s) uses production output of predecessor station(s) as # input(s) for its production, required production amount of predecessor station(s) depends on # required production amount of successor station(s). Hence, required production amount of a # successor station multiplies required production amount of predecessor station(s). Therefore # backward chaining based simulation is used, so this multiplication can be reflected among # the whole production line. # # 5- Addition to visual presentation of simulation results through 'Chart' objects, the Algorithm # stores results (at the moment just execution time) to be presented by BROWSER on UI. # #----------------------------------------------------------------------------------------------------------------- #***************************************************************************************************************** #global variables required for time conversion # wdpy: working days per year # whpd: working hours per day SETG wdpy:365 SETG whpd:24 #object id of Buffer, where the algorithm is triggered SET nCurrentBufferObjid:(objid) #modelid of model, where the Buffer is placed CC "Core" GET_MODEL_ID objid:(nCurrentBufferObjid) SET nCurrentModelID:(modelid) #Content holder for Simulation Results Browser SETG sBrowserContent:"" # unmark all objects eventually marked by previous simulation runs CC "Modeling" UNDYE_ALL modelid: (nCurrentModelID) #reset all required quantities eventually defined by previous simulation runs CC "AQL" EVAL_AQL_EXPRESSION expr: ("<\"Buffer\">") modelid: (nCurrentModelID) SETL lBufferNodeList:(objids) FOR sBufferNode in: (lBufferNodeList) { CC "Core" SET_ATTR_VAL objid: (VAL sBufferNode) attrname: ("Required quantity") val: (0) } #let user enter production amount CC "AdoScript" EDITFIELD title:"Quantity of Product to be produced" caption:"Quantity:" text:"0" SET nProductionAmount:0 # if there is no error start simulation IF (ecode = 0) { SET nProductionAmount:(VAL text) #update attribute "Required quantity" from selected buffer object in each iteration for dynamic representation CC "Core" SET_ATTR_VAL objid:(nCurrentBufferObjid) attrname: ("Required quantity") val: (nProductionAmount) #update help attribute "ProductionAmount" for dynamic representation in "Chart" CC "Core" SET_ATTR_VAL objid: (nCurrentBufferObjid) attrname: ("ProductionAmount") val: (nProductionAmount) SET lGroupNodeList:"" #Loop through production amount. FOR nCounter from: 1 to: (nProductionAmount) { # remove all previous marks CC "Modeling" UNDYE_ALL modelid: (nCurrentModelID) CC "AdoScript" MSGWIN ((STR nCounter)+". Product is being produced") CC "AdoScript" MSGWIN hide #empty help attribute RequiredQuantityArray in current buffer object. This attribute is used for #representation of simulation results via assigned 'Chart' objects IF (nCounter = 1) { CC "Core" SET_ATTR_VAL objid: (nCurrentBufferObjid) attrname: ("RequiredQuantityArray") val: ("") } CC "Core" GET_ATTR_VAL objid: (nCurrentBufferObjid) attrname: ("RequiredQuantityArray") SETL initialRequiredQuantityArray: (val) SETL newRequiredQuantityArray: (tokcat ( initialRequiredQuantityArray , (STR nCounter) , " " ) ) CC "Core" SET_ATTR_VAL objid: (nCurrentBufferObjid) attrname: ("RequiredQuantityArray") val: (newRequiredQuantityArray) #initialize help attribute AvailableQuantityArray, if it is the first iteration. This attribute is used for #representation of simulation results via assigned 'Chart' objects IF (nCounter = 1) { CC "Core" GET_ATTR_VAL objid: (nCurrentBufferObjid) attrname: ("Available quantity") CC "Core" SET_ATTR_VAL objid: (nCurrentBufferObjid) attrname: ("AvailableQuantityArray") val: (STR val) } #persist initial value from help attribute AvailableQuantityArray from previous iteration CC "Core" GET_ATTR_VAL objid: (nCurrentBufferObjid) attrname: ("AvailableQuantityArray") SETL initialRequiredQuantityArray: (val) #get current available quantity from current buffer object CC "Core" GET_ATTR_VAL objid: (nCurrentBufferObjid) attrname: ("Available quantity") SETL nAvailableQuantity:(val) #update value from help attribute AvailableQuantityArray with adding current available quantity SETL newAvailableQuantityArray: (tokcat ( initialRequiredQuantityArray , (STR nAvailableQuantity) , " " ) ) CC "Core" SET_ATTR_VAL objid: (nCurrentBufferObjid) attrname: ("AvailableQuantityArray") val: (newAvailableQuantityArray) ###start with identifying the tree### #get next predecessor group objects. GET_NEXT_GROUPS nBufferObjid:(nCurrentBufferObjid) lNodeList:lGroupNodeList nModelId:(nCurrentModelID) nRequiredQuantity:(nCounter) nProductionAmount:(nProductionAmount) nCounter:(nCounter) } #trigger collection of simulation results content from each Station and present them on UI CREATE_SIMULATION_RESULTS_BROWSER lGroupNodes:lGroupNodeList } ################################################################################################################## # GET_NEXT_GROUPS ################################################################################################################## # # Description: This procedure gets predecessor stations (Group objects) backwards from given Buffer Object. # Requirements of parts in RECORD ATTRIBUTE 'Bill of Materials' will be updated according to # formula (required production amount of successor stations * required part amount # per unit production* Quantity specified outgoing 'Part flow' (required input to be stored in successor # buffer)) # Execution time for current production iteration is registered # For each station (Group objects)'GET_NEXT_BUFFERS' procedure is triggered To get predecessor buffer(s) # #----------------------------------------------------------------------------------------------------------------- # # Input: - nBufferObjid (integer) - objid of Buffer Object # - nModelId (integer) - Model-id # - nProductionAmount (real) - Production Amount given by user # - nRequiredQuantity (real) - Required quantity by successor station # - nCounter (integer) - Iteration Counter (number of product) # #----------------------------------------------------------------------------------------------------------------- # # Output: - lNodeList (reference) - List of nodes in tree used for simulation # ################################################################################################################## PROCEDURE global GET_NEXT_GROUPS nBufferObjid:integer lNodeList:reference nModelId:integer nRequiredQuantity:real nProductionAmount:real nCounter:integer { #mark nodes of tree used in simulation CC "Modeling" DYE (nBufferObjid ) error-mark CC "Core" GET_OBJ_NAME objid: (nBufferObjid) SETL sBufferName:(objname) CC "Core" GET_CLASS_ID objid: (nBufferObjid) SETL nClassId: (classid) CC "Core" GET_CLASS_NAME classid: (nClassId) SETL sClassName:(classname) CC "Core" GET_CLASS_ID classname: ("Group") SET nGroupClassId: (classid) CC "Core" GET_ATTR_ID classid:(nGroupClassId) attrname:("Bill of Materials") SET nBOMRecAttrid:(attrid) #get all stations (Group Objects) which are related to the given buffer object #with incoming 'Parts flow' relation CC "AQL" EVAL_AQL_EXPRESSION expr: ("({\""+sBufferName+"\":\""+sClassName+"\"}<-\"Parts flow\">\"Group\"<)") modelid: (nModelId) SETL lChilderenGroupNodeList:(objids) FOR sNode in: (lChilderenGroupNodeList) { SETL nNode:(VAL sNode) CC "Core" GET_OBJ_NAME objid: (nNode) SETL sGroupName:(objname) #get the connector object between the buffer in row and its predecessor station (Group object) #then get the quantity that will produced by the station store/transport by the buffer CC "AQL" EVAL_AQL_EXPRESSION expr: ("(({\""+sGroupName+"\"}-><\"Parts flow\">) AND ({\""+sBufferName+"\"}<-<\"Parts flow\">))") modelid: (nModelId) CC "Modeling" DYE (VAL objids ) error-mark CC "Core" GET_ATTR_VAL objid: (VAL objids) attrname:("Quantity") SETL nQuantity:(val) #update BoM CC "Core" GET_REC_ATTR_ROW_COUNT objid:(nNode) attrid:(nBOMRecAttrid) SET nBOMRecRowCount:(count) FOR i from:(nBOMRecRowCount) to:(1) by:(-1) { CC "Core" GET_REC_ATTR_ROW_ID objid:(nNode) attrid:(nBOMRecAttrid) index:(i) CC "Core" GET_ATTR_VAL objid:(rowid) attrname: ("Required quantity") SETL nRequiredQuantityPerUnit: (val) # Hint: initial required quantity from record table is taken as required quantity per unit CC "Core" SET_ATTR_VAL objid:(rowid) attrname: ("Simulation result") val: (nRequiredQuantityPerUnit*nRequiredQuantity*nQuantity) } #clean execution time array at beginning IF (nCounter = 1) { CC "Core" SET_ATTR_VAL objid: (nNode) attrname: ("ExecutionTimeArray") val: ("") } #set execution time array CC "Core" GET_ATTR_VAL objid: (nNode) attrname: ("Execution time") as-string SETL sExpectedExecutionTime:(val) ADOTIME_TO_SEC (sExpectedExecutionTime) seconds:nExpectedExecutionTime CC "AQL" EVAL_AQL_EXPRESSION expr: ("{\""+sGroupName+"\"}<-\"Sets (generic) \">\"Random generator (generic)\"<") modelid: (nModelId) SETL sRandGenObjid:(objids) # if there is assigned random generator to the group object, run random generation IF (sRandGenObjid !="") { RANDOM_GENERATOR nObjid:(nNode) modelId:(nModelId) variable:(nExpectedExecutionTime) randomValue:nRealExecutionTime SET nRealExecutionTime:((nRealExecutionTime)/60) } # if there is no assigned random generator to the group object, get execution time from group as it is. ELSE { SET nRealExecutionTime:((nExpectedExecutionTime)/60) } #get the initial value from "ExecutionTimeArray" attribute of current group node CC "Core" GET_ATTR_VAL objid: (nNode) attrname: ("ExecutionTimeArray") as-string SET sInitialExecutionTimeArray: (val) #add new value to "ExecutionTimeArray" SET sNewExecutionTimeArray:(tokcat(sInitialExecutionTimeArray, (STR nRealExecutionTime), " ")) #set new "ExecutionTimeArray" ExecutionTimeArray" attribute of current group node CC "Core" SET_ATTR_VAL objid: (nNode) attrname: ("ExecutionTimeArray") val: (sNewExecutionTimeArray) #set current Production Amount in current group node. Production Amount is the iteration counter, #which is needed for dynamic "Chart" representation CC "Core" SET_ATTR_VAL objid: (nNode) attrname: ("ProductionAmount") val: (nProductionAmount) CC "AdoScript" SLEEP ms:20 #get next children buffer nodes of current group node GET_NEXT_BUFFERS nGroupObjid:(nNode) lNodeList:lNodeList nModelId: (nModelId) nRequiredQuantity:(nRequiredQuantity*nQuantity) nProductionAmount:(nProductionAmount) nCounter:(nCounter) } } ################################################################################################################## # GET_NEXT_BUFFERS ################################################################################################################## # # Description: This procedure gets predecessor buffers (buffer objects) backwards from given station (Group # Object.) # Required quantity to be delivered by each buffer is calculated with the # formula (required production amount of successor stations * required part amount # per unit production* Quantity specified outgoing 'Part flow' (required input by successor stations)) # Available parts for current production iteration is registered # For each buffer 'GET_NEXT_GROUP' procedure is triggered to get predecessor stations(s) #----------------------------------------------------------------------------------------------------------------- # # Input: - nGroupObjid (integer) - objid of Group Object (station) # - nModelId (integer) - Model-id # - nProductionAmount (real) - Production Amount given by user # - nRequiredQuantity (real) - Required quantity by successor station # - nCounter (integer) - Iteration Counter (number of product) # #----------------------------------------------------------------------------------------------------------------- # # Output: - lNodeList (reference) - List of nodes in tree used for simulation # ################################################################################################################## PROCEDURE global GET_NEXT_BUFFERS nGroupObjid:integer lNodeList:reference nModelId:integer nRequiredQuantity:real nProductionAmount:real nCounter:integer { CC "Modeling" DYE (nGroupObjid) error-mark CC "Core" GET_OBJ_NAME objid: (nGroupObjid) SETL sGroupName:(objname) CC "Core" GET_CLASS_ID objid: (nGroupObjid) SETL nClassId: (classid) CC "Core" GET_CLASS_NAME classid: (nClassId) SETL sClassName:(classname) #get all buffers which are related to the given station (Group Object) with incoming 'Parts flow' #relation CC "AQL" EVAL_AQL_EXPRESSION expr: ("({\""+sGroupName+"\":\""+sClassName+"\"}<-\"Parts flow\">\"Buffer\"<)") modelid: (nModelId) SETL lChilderenBufferNodeList: (objids) FOR sNode in: (lChilderenBufferNodeList) { SETL nNode:(VAL sNode) #Production Amount CC "Core" SET_ATTR_VAL objid: (nNode) attrname: ("ProductionAmount") val: (nProductionAmount) #set required quantity CC "Core" GET_OBJ_NAME objid: (nNode) SETL sBufferName:(objname) CC "AQL" EVAL_AQL_EXPRESSION expr: ("(({\""+sGroupName+"\"}<-<\"Parts flow\">) AND ({\""+sBufferName+"\"}-><\"Parts flow\">))") modelid: (nModelId) CC "Modeling" DYE (VAL objids ) error-mark CC "Core" GET_ATTR_VAL objid: (VAL objids) attrname:("Quantity") SETL nQuantity:(val) SETL nNewRequiredQuanitity: (nRequiredQuantity*nQuantity) #fill chart arrays ##RequiredQuantityArray ###empty the array IF (nCounter = 1) { CC "Core" SET_ATTR_VAL objid: (nNode) attrname: ("RequiredQuantityArray") val: ("") } CC "Core" GET_ATTR_VAL objid: (nNode) attrname: ("RequiredQuantityArray") SETL initialRequiredQuantityArray: (val) SETL newRequiredQuantityArray: (tokcat ( initialRequiredQuantityArray , (STR nNewRequiredQuanitity) , " " ) ) CC "Core" SET_ATTR_VAL objid: (nNode) attrname: ("RequiredQuantityArray") val: (newRequiredQuantityArray) #AvailableQuantityArray IF (nCounter = 1) { CC "Core" GET_ATTR_VAL objid: (nNode) attrname: ("Available quantity") CC "Core" SET_ATTR_VAL objid: (nNode) attrname: ("AvailableQuantityArray") val: (STR val) } CC "Core" GET_ATTR_VAL objid: (nNode) attrname: ("AvailableQuantityArray") SETL initialRequiredQuantityArray: (val) CC "Core" GET_ATTR_VAL objid: (nNode) attrname: ("Available quantity") SETL nAvailableQuantity:(val) SETL newAvailableQuantityArray: (tokcat( initialRequiredQuantityArray , (STR nAvailableQuantity) , " " ) ) CC "Core" SET_ATTR_VAL objid: (nNode) attrname: ("AvailableQuantityArray") val: (newAvailableQuantityArray) CC "Core" SET_ATTR_VAL objid: (nNode) attrname: ("Required quantity") val: (nRequiredQuantity*nQuantity) #get next CC "AdoScript" SLEEP ms:20 GET_NEXT_GROUPS nBufferObjid:(nNode) lNodeList:lNodeList nModelId: (nModelId) nRequiredQuantity:(nRequiredQuantity*nQuantity) nProductionAmount:(nProductionAmount) nCounter:(nCounter) } SETL lNodeList:(tokunion(lNodeList, STR nGroupObjid)) } ################################################################################################################## # CREATE_SIMULATION_RESULTS_BROWSER ################################################################################################################## # # Description: This procedure visits registries (e.g. ExecutionTimeArray) of each station used during # simulation. # Triggers procedure 'CALCULATE_AVERAGE' to calculate averages # Creates content structure to present simulation results via 'BROWSER' #----------------------------------------------------------------------------------------------------------------- # # Input: - lGroupNodes (reference) - stations (Group) nodes in tree used for simulation # #----------------------------------------------------------------------------------------------------------------- # # Output: - # ################################################################################################################## PROCEDURE CREATE_SIMULATION_RESULTS_BROWSER lGroupNodes:reference { SETL sFirstRowStations:" " SETL sSecondRowAvgExecutionTimes:"Average Execution Time: " SETL sThirdRowAvgWaitingTimes:"Average Waiting Time: " SETL sForthRowAvgTransportTimes:"Average Transport Time: " SETL sFifthRowAvgCost:"Average Cost: " FOR sGroupNodes in: (lGroupNodes) { SETL nGroupNodes: (VAL sGroupNodes) CC "Core" GET_OBJ_NAME objid: (nGroupNodes) SET sFirstRowStations: (tokcat(sFirstRowStations, (objname), (";"))) CC "Core" GET_ATTR_VAL objid: (nGroupNodes) attrname: ("ExecutionTimeArray") SETL sExectionTimeArray:(val) SET aExectionTimeArray: (valarray(sExectionTimeArray, " ")) CALCULATE_AVERAGE registry: (aExectionTimeArray) average:average SET sSecondRowAvgExecutionTimes: (tokcat (sSecondRowAvgExecutionTimes, (STR average), (";"))) #place holders. Potential extensions to simulation results browser SET sThirdRowAvgWaitingTimes: (tokcat (sThirdRowAvgWaitingTimes, ("N/A"),(";"))) SET sForthRowAvgTransportTimes: (tokcat (sForthRowAvgTransportTimes, ("N/A"),(";"))) SET sFifthRowAvgCost: (tokcat (sFifthRowAvgCost, ("N/A"),(";"))) } SET sBrowserContent: (tokcat (sFirstRowStations, sSecondRowAvgExecutionTimes, ("\t"))) SET sBrowserContent: (tokcat (sBrowserContent, sThirdRowAvgWaitingTimes, ("\t"))) SET sBrowserContent: (tokcat (sBrowserContent, sForthRowAvgTransportTimes, ("\t"))) SET sBrowserContent: (tokcat (sBrowserContent, sFifthRowAvgCost, ("\t"))) CC "AdoScript" BROWSER title:"Simulation Results" content:(sBrowserContent) linesep:"\t" adjust-rows with-handlecolumn alignment:"LR" header:"Save\nsimulation results" print-header:"Print\nsimulation results" } ################################################################################################################## # CALCULATE_AVERAGE ################################################################################################################## # # Description: This procedure extends the functionality of menu entry "New" # If version numbering is being used it ensures that the newly created model will get # the correct version number, and then a history entry is being added. # If we don't use the version numbering it only adds the history entry. #----------------------------------------------------------------------------------------------------------------- # # Input: - registry (array) - Registry of any numeric simulation results # #----------------------------------------------------------------------------------------------------------------- # # Output: - average (reference) - Average of entries in the registry # ################################################################################################################## PROCEDURE CALCULATE_AVERAGE registry:array average:reference { SET nLenArray: (LEN registry) SET nTotal:0 FOR i from:0 to:(nLenArray-1) { SET nTotal:(nTotal+registry[i]) } SET average:(nTotal/nLenArray) } ################################################################################################################## # RANDOM_GENERATOR ################################################################################################################## # # Description: This procedure gets distribution type of random generator assigned to a object. # According to type of random generator it decides which attributes values should be gathered # from random generator object defined by user, overload distribution function, create and deliver # random value back. # This procedures relias on 11 distribution functions implemented in 'ASC_RandomDistributions.asc' namely; # - Standard Uniform Distribution # - Uniform Distribution # - Standard Normal Distribution # - Normal Distribution # - Triangular Distribution # - Exponential Distribution # - Discrete Distribution # - Discrete Uniform Distribution # - Bernoulli Distribution # - Rademacher Distribution # - Coin Toss #----------------------------------------------------------------------------------------------------------------- # # Input: - nObjid (integer) - Objid of Object, to which a random generator is assigned # - modelId (integer) - Model-id # - variable (real) - any predefined expected (numeric) value # #----------------------------------------------------------------------------------------------------------------- # # Output: - randomValue (reference) - Randomly generated value # ################################################################################################################## PROCEDURE global RANDOM_GENERATOR nObjid:integer modelId:integer variable:real randomValue:reference { CC "Core" GET_OBJ_NAME objid: (nObjid) SET sObjName:(objname) CC "AQL" EVAL_AQL_EXPRESSION expr: ("{\""+sObjName+"\"}<-\"Sets (generic)\">\"Random generator (generic)\"<") modelid: (modelId) SET sRandomGenObjId: (objids) SET nRandomGenObjId: (VAL sRandomGenObjId) #get distribution type of random generator CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Distribution type") SETL sDT:(val) SET randomValue:0 #get values and overload random generation function according to distribution type IF (sDT = ("Standard Uniform Distribution")) { SET randomValue: (randomStandardUniformDist()) SET randomValue: (variable*randomValue) } IF (sDT = ("Uniform Distribution")) { CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Lower limit") SET rea_lowlimit:(val) CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Upper limit") SET rea_uplimit:(val) SET randomValue: (randomUniformDist(rea_lowlimit, rea_uplimit)) } IF (sDT = ("Standard Normal Distribution")) { SET randomValue: (randomStandardNormalDist()) SET randomValue: (variable*randomValue) } IF (sDT = ("Normal Distribution")) { CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Expectancy value") SET rea_expectancy:(val) CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Standard deviation") SET rea_stddev:(val) SET randomValue: (randomNormalDist(rea_expectancy, rea_stddev)) } IF (sDT = ("Triangular Distribution")) { CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Lower limit") SET rea_lowlimit:(val) CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Upper limit") SET rea_uplimit:(val) CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Mode") SET rea_mode:(val) SET randomValue: (randomTriangularDist(rea_lowlimit, rea_mode, rea_uplimit)) } IF (sDT = ("Exponential Distribution")) { CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Scale") SET rea_scale:(val) SET randomValue:(randomExponentialDist(rea_scale)) SET randomValue:(variable*randomValue) } IF (sDT = ("Discrete Distribution Positions")) { CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Probabilities array") SET arr_probabilites:(val) SET arr_probabilites:(valarray(arr_probabilites)) SET randomValue:(randomDiscreteDistPositions(arr_probabilites)) SET randomValue:(variable*randomValue) } IF (sDT = ("Discrete Distribution Values")) { CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Probabilities map") SET map_probabilites:(val) SET map_probabilites:(strarray(map_probabilites)) SET randomValue:(randomDiscreteDistValues(map_probabilites)) SET randomValue:(variable*randomValue) } IF (sDT = ("Discrete Uniform Distribution")) { CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Lower limit") SET int_lowlimit:(INT val) CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Upper limit") SET int_uplimit:(INT val) SET randomValue:(randomDiscreteUniformDist(int_lowlimit, int_uplimit)) } IF (sDT = ("Bernoulli Distribution")) { CC "Core" GET_ATTR_VAL objid: (nRandomGenObjId) attrname: ("Probability") SET rea_prob:(val) SET randomValue:(randomBernoulliDist(rea_prob)) } IF (sDT = ("Rademacher Distribution")) { SET randomValue:(randomRademacherDist()) } IF (sDT = ("Coin Toss")) { SET randomValue:(randomCoinToss()) } }